<!DOCTYPE html>
<html lang="en">

<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>14.捕获鼠标</title>
</head>

<body>
	<canvas id="canvas"></canvas>
	<script src="https://webglfundamentals.org/webgl/resources/webgl-utils.js"></script>
	<script src="https://webglfundamentals.org/webgl/resources/m4.js"></script>
	<script src="https://webglfundamentals.org/webgl/resources/primitives.js"></script>
	<script src="https://webglfundamentals.org/webgl/resources/texture-utils.js"></script>
	<script src="https://webglfundamentals.org/webgl/resources/chroma.min.js"></script>
	<script type="x-shader/x-vertex" id="vertex">
		attribute vec4 a_position;
		attribute vec3 a_normal;

		uniform mat4 u_projection;
		uniform mat4 u_view;
		uniform mat4 u_world;

		
		attribute vec2 a_texcoord;
		
		varying vec2 v_texCoord;

		varying vec3 v_normal;
		
		varying vec3 v_worldPosition;
		varying vec3 v_worldNormal;
		
		void main(){
			gl_Position =  u_projection * u_view * u_world * a_position;
			v_texCoord=a_texcoord;
			v_normal = normalize(a_position.xyz);
			
			v_worldPosition = (u_world * a_position).xyz;

			// orient the normals and pass to the fragment shader
			v_worldNormal = mat3(u_world) * a_normal;
		}
	</script>
	<script type="x-shader/x-fragment" id="fragment">
		precision mediump float;
		
		//uniform sampler2D u_texture;
		uniform vec4 u_color;
		varying vec2 v_texCoord;
		void main(){
			//vec4 diffuseColor = texture2D(u_texture, v_texCoord);//纹理
			//gl_FragColor = diffuseColor;
			gl_FragColor=u_color;
			//gl_FragColor.r=1.;
			//gl_FragColor.g=0.;
			//gl_FragColor.b=1.;
			//gl_FragColor.a=1.;
		}
	</script>
	<script>
		const canvas = document.getElementById("canvas");
		canvas.width = window.innerWidth
		canvas.height = window.innerHeight
		const gl = canvas.getContext("webgl")
		const aspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
		const programInfo = webglUtils.createProgramInfo(gl, ["vertex", "fragment"])
		const cubeBufferInfo = primitives.createCubeBufferInfo(
			gl,
			30
		);
		gl.useProgram(programInfo.program)
		const cameraMatrix = m4.lookAt([50, 50, 150], [0, 0, 0], [0, 1, 0])
		const viewMatrix = m4.inverse(cameraMatrix)
		function degToRad(d) {
			return d * Math.PI / 180;
		}

		var texture = gl.createTexture();
		const arrs = []
		var cameraPosition = [0, 0, 2];
		var world = m4.translation(0, 0, 0)
		let t = 0
		const image = new Image();
		var width = gl.canvas.width;
		var height = gl.canvas.height;
		// var data = new Uint8Array(width * height * 4)
		// gl.bindTexture(gl.TEXTURE_2D, texture);
		// gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
		// gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
		// gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
		// gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
		// // 将图像数据加载到纹理对象中
		// gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
		// // gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA,256,256,0, gl.UNSIGNED_BYTE, data);


		// const level = 0;
		// const internalFormat = gl.RGBA;
		// const border = 0;
		// const format = gl.RGBA;
		// const type = gl.UNSIGNED_BYTE;
		// var data = null;
		// gl.texImage2D(gl.TEXTURE_2D, level, internalFormat,width, height, border,format, type, data);

		// gl.generateMipmap(gl.TEXTURE_2D);

		// gl.viewport(0, 0, width, height);
		// const fb = gl.createFramebuffer();
		// gl.bindFramebuffer(gl.FRAMEBUFFER, fb);

		// // 附加纹理为第一个颜色附件
		// gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
		// const targetTexture = gl.createTexture();
		// gl.bindTexture(gl.TEXTURE_2D, targetTexture);
		// image.onload=(e=>{
		// 	gl.bindTexture(gl.TEXTURE_2D, targetTexture);
		// 	gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA,gl.RGBA,gl.UNSIGNED_BYTE,image);
		// 	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
		// 	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
		// 	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
		// 	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);

		// })	
		// image.src = '/webgl学习.png';
		// image.src = '/f-texture.png';
		gl.enable(gl.CULL_FACE);
		gl.enable(gl.DEPTH_TEST);


		function rand(min, max) {
			return Math.random() * (max - min) + min;
		}

		let mouseX = -1;
		let mouseY = -1;
		const projectionMatrix = m4.perspective(degToRad(60), aspect, 1, 2000);
		const drawInfos = []
		for (let index = 0; index < 150; index++) {
			const id = index + 1
			const color = [
				((id >> 0) & 0xFF) / 0xFF,
				((id >> 8) & 0xFF) / 0xFF,
				((id >> 16) & 0xFF) / 0xFF,
				((id >> 24) & 0xFF) / 0xFF,
			]
			const translation = [rand(-500, 500), rand(-500, 500), rand(-500, 0)]
			let world = m4.translation(translation[0], translation[1], translation[2])
			const object = {
				id,
				programInfo,
				uniforms: {
					u_view: viewMatrix,					//视图
					u_projection: projectionMatrix,		//投影
					u_world: world,	//世界
					u_color: color
				},
				model: cubeBufferInfo
			}
			drawInfos.push(object)
		}
		// gl.bindFramebuffer(gl.FRAMEBUFFER, null);
		gl.viewport(0, 0, canvas.width, canvas.height);


		let pixelX = mouseX * gl.canvas.width / gl.canvas.clientWidth;
		let pixelY = gl.canvas.height - mouseY * gl.canvas.height / gl.canvas.clientHeight - 1;
		let clickId = -1;
/*
//先创建纹理
//绑定并设置纹理内容

const targetTexture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D,targetTexture)
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA,width, height, 0,gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
//创建帧缓存区
//绑定帧缓存区
//附加纹理
const fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, targetTexture, 0);

//创建渲深度缓冲区并绑定
//初始化渲染对象存储
//附加到帧缓存区
const depthBuffer = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, gl.canvas.width, gl.canvas.height);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthBuffer);

//深度缓存区可以在绘制时有深度，从而更准确的定位元素
*/
		const targetTexture = gl.createTexture();
		gl.bindTexture(gl.TEXTURE_2D,targetTexture)
		gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA,width, height, 0,gl.RGBA, gl.UNSIGNED_BYTE, null);
		gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
		gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
		gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);

		const fb = gl.createFramebuffer();
		gl.bindFramebuffer(gl.FRAMEBUFFER, fb);

		const attachmentPoint = gl.COLOR_ATTACHMENT0;
		const level = 0;
		gl.framebufferTexture2D(gl.FRAMEBUFFER, attachmentPoint, gl.TEXTURE_2D, targetTexture, level);

		const depthBuffer = gl.createRenderbuffer();
		gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer);
		gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height);
		gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthBuffer);
		function drawScene() {

			function a(b, clickId) {
				drawInfos.forEach((i, index) => {
					const object = drawInfos[index]
					const id = object.id
					if (b) {
						object.uniforms.u_color = [
							((id >> 0) & 0xFF) / 0xFF,
							((id >> 8) & 0xFF) / 0xFF,
							((id >> 16) & 0xFF) / 0xFF,
							((id >> 24) & 0xFF) / 0xFF,
						]
					} else {
						if (clickId === id) {
							object.uniforms.u_color = [1, 0, 0, 1]
						} else {
							object.uniforms.u_color = [0, 1, 0, 1]
						}
					}
					webglUtils.setBuffersAndAttributes(gl, object.programInfo, object.model);
					webglUtils.setUniforms(object.programInfo, object.uniforms);

					webglUtils.drawBufferInfo(gl, object.model);
				})
			}


			// gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
			pixelX = mouseX * gl.canvas.width / gl.canvas.clientWidth;
			pixelY = gl.canvas.height - mouseY * gl.canvas.height / gl.canvas.clientHeight - 1;
			gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
			gl.viewport(0, 0, width, height);
			gl.enable(gl.CULL_FACE);
			gl.enable(gl.DEPTH_TEST);
			gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
			a(true)
			const data = new Uint8Array(4);
			gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
			gl.finish();

			gl.readPixels(
				pixelX,            // x
				pixelY,            // y
				1,                 // width
				1,                 // height
				gl.RGBA,           // format
				gl.UNSIGNED_BYTE,  // type
				data);             // typed array to hold result
			clickId = data[0] + (data[1] << 8) + (data[2] << 16) + (data[3] << 24);
			gl.bindFramebuffer(gl.FRAMEBUFFER, null);
			a(false,clickId)
			// gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
			// gl.bindTexture(gl.TEXTURE_2D, targetTexture);
			// gl.viewport(0, 0, width, height);
			// gl.clearColor(0.8, 1, 1, 1);   // clear to blue
			// gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
			// drawCube()
			// gl.bindFramebuffer(gl.FRAMEBUFFER, null);
			// gl.bindTexture(gl.TEXTURE_2D, texture);
			// gl.viewport(0, 0, canvas.width,canvas.height);
			// gl.clearColor(1, 1, 1, 1);   // clear to blue
			// gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
			// drawCube()
			requestAnimationFrame(drawScene);
		}

		// const targetTexture = gl.createTexture();
		// gl.bindTexture(gl.TEXTURE_2D, targetTexture);
		// gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
		// gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
		// gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);


		requestAnimationFrame(drawScene);
		canvas.onmousemove = (e) => {
			const rect = canvas.getBoundingClientRect();
			mouseX = e.clientX - rect.left;
			mouseY = e.clientY - rect.top;
			const {x, y} = e
		}
	</script>
</body>

</html>